<?php

namespace App\Logics;


use App\Models\Order;
use App\Models\OrderMoney;
use App\Models\OrderUser;
use App\Models\SiteConfig;
use App\Models\User;
use App\Models\UserAuth;
use App\Models\UserMoney;
use App\Models\UserPay;
use App\Models\UserProfit;
use App\Models\UserProfit2;
use App\Models\UserWithdraw;
use App\Service\Base\Logic;
use App\Service\WeChat\MiniPayV3;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Request;


class MiniPayLogicV3 extends Logic
{

    // 提现
    //   https://cloud.tencent.com/developer/article/2233513
    //   https://www.cnblogs.com/leaf-cq/p/14302927.html
    //   小程序 提现 v3 php


    // 小程序支付
    //   独立，不依赖于其他程序

    // 实例化 小程序支付v3
    protected function payV3()
    {
        // 查询 配置信息
        $config = Config::get('wx');
        if(empty($config['wx_mini_appid']) || empty($config['wx_mini_key']) || empty($config['wx_mchid']) || empty($config['serial_no']) || empty($config['pay_api3_key'])){
            return $this->_returnFail('请配置微信小程序信息！');
        }

        $payV3 = new MiniPayV3($config['wx_mini_appid'], $config['wx_mini_key'], $config['wx_mchid'], $config['serial_no'], $config['pay_api3_key']);

        return $payV3;
    }

    #######################################################################################
    //  小程序支付：测试
    public function test()
    {
        $opt        = $this->option();
        $notify_url = $this->notifyUrl('auth');  // 回调
        $to_mini    = $opt->getData('to_mini', 0, 'intval');  // 是否转换为小程序请求调用的json 默认不转换

        // 判断支付金额
        $money   = 0.01;
        $openid  = 'o4H167e6PNOYgpwJKihvj1ZdqIk4';
        $orderNo = date("YmdHis").'_'.random(4);
        $body    = '测试支付';

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        // 执行下单操作
        $result = $payV3->makeMiniPay($body, $orderNo, $openid, $money, $notify_url);
        if(!empty($result['code'])){
            return $this->_returnFail($result['message']);
        }

        if($to_mini){
            return $this->toMiniJson($result['prepay_id']);
        }

        return $result;
    }

    // 获取  serial_no
    public function getSerialNo()
    {
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        $serial_no = $payV3->merchantSerialNo();

        return $serial_no;
    }

    //  小程序退款：测试
    public function testRefund()
    {
        $notify_url = $this->notifyUrl('auth');  // 回调

        // 判断支付金额
        $money   = 0.01;
        $orderNo = date("YmdHis").'_'.random(4);  // 新订单号
        $old_no  = '534_20240828173023_6168';    // 以前支付使用的订单号

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        // 执行
        $result = $payV3->refund($old_no, $orderNo, $money, $notify_url);
        $result = json_decode($result, true);

        return $result;
    }

    // 提现测试
    public function testTransfer()
    {
        $notify_url = $this->notifyUrl('withdraw');  // 回调

        // 判断支付金额
        $money   = 0.01;
        $orderNo = date("YmdHis").'A'.random(4);  // 新订单号 中间不能是下划线，只能是字母
        $desc    = '用户提现测试一下';
        $openid  = 'o4H167U1H0ASYznNJ1LDZgzw3jQg';

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        // 执行
        $result = $payV3->WechatTransfer($desc, $orderNo, $openid, $money, $notify_url);
        $result = json_decode($result, true);

        return $result;
    }

    #######################################################################################
    ## 下单 + 支付

    //  小程序支付：报名参加 + 获取支付
    public function eventAndPay($myUid)
    {
        $notify_url = $this->notifyUrl('event');  // 回调

        $opt       = $this->option();
        $event_id  = $opt->getData('event_id', 0, 'intval');
        $share_uid = $opt->getData('share_uid', 0, 'intval');
        $users     = $opt->getData('users', [], 'is_array');  // 报名用户列表
        $money     = $opt->getData('money', 0, 'floatval');
        $openid    = $opt->getData('openid', null, 'trim');
        $to_mini   = $opt->getData('to_mini', 0, 'intval');  // 是否转换为小程序请求调用的json 默认不转换

        // 判断
        if(empty($money)){
            return $this->_returnFail('请传递支付金额！');
        }
        if(empty($users)){
            return $this->_returnFail('请指定报名用户！');
        }

        // 执行下单
        $orderDb = new Order();
        $result  = $orderDb->makeOrder($myUid, $event_id, $users, $share_uid, $money);
        if($result === false){
            return $this->_returnFail($orderDb->getError());
        }
        // 判断支付金额
        $_money  = $result['money'];
        $orderNo = $result['order_no'];
        $body    = '报名参加活动';
        if($_money != $money){
            return $this->_returnFail('支付金额错误！');
        }
        if(empty($orderNo)){
            return $this->_returnFail('请传递订单号！');
        }

        // 保存支付信息
        $res = $this->savePayLog($myUid, $orderNo, $money, $body, $result['id']);
        if($res === false){
            return $this->_returnFail('保存支付信息失败');
        }

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }
        $result = $payV3->makeMiniPay($body, $orderNo, $openid, $money, $notify_url);
        if(!empty($result['code'])){
            return $this->_returnFail($result['message']);
        }
        // 给小程序返回可以直接调起支付的的json（也可以小程序自己制作）
        if($to_mini){
            return $this->toMiniJson($result['prepay_id']);
        }

        return $result;
    }

    //  小程序支付：认证 + 获取支付
    public function authAndPay($myUid)
    {
        $notify_url = $this->notifyUrl('auth');  // 回调

        $opt     = $this->option();
        $money   = $opt->getData('money', 0, 'floatval');
        $openid  = $opt->getData('openid', null, 'trim');
        $to_mini = $opt->getData('to_mini', 0, 'intval');  // 是否转换为小程序请求调用的json 默认不转换
        $_type   = $opt->getData('auth_type', null, 'trim');
        $_allow  = $opt->getData('school_allow', null, 'trim');

        // 查询
        if(empty($money)){
            return $this->_returnFail('请传递支付金额！');
        }

        // 认证以前请先完善资料
        $userDb = new User();
        $uinfo  = $userDb->where('id', $myUid)->first();
        $mobile = $uinfo['mobile'];
        $opt->throwIf(empty($mobile), '请先完善个人资料！');

        // 判断是否已经提交认证
        //$opt->throwIf(empty($code), '请填写验证码！');
        $opt->throwIf($uinfo['verify'] == 1, '你已经通过认证审核！');
        $opt->throwIf($uinfo['is_auth'], '你已经申请认证,请等待审核！');
        $opt->throwIf(empty($_type), '请选择认证类型！');
        $opt->throwIf(($_type == 'school') && empty($_allow), '请学校请上传办学资质！');

        // 添加的数据
        $data = [
            'uid'          => $myUid,
            'auth_type'    => $_type,
            'auth_name'    => $opt->getData("auth_name", null, "trim"),
            'city'         => $opt->getData("city", null, "trim"),
            'grade'        => $opt->getData("grade", null, "trim"),
            'telephone'    => $opt->getData("telephone", null, "trim"),
            'address'      => $opt->getData("address", null, "trim"),
            'description'  => $opt->getData("description", null, "trim"),
            'license_img'  => $opt->getData("license_img", null, "trim"),
            'school_allow' => $_allow,
            'is_pay'       => 0,
            'verify'       => 0,
            //'form_time'    => 0,
            //'end_time'     => 0,
            //'ctime'        => $opt->getData("ctime", null, "intval"),
            //'mtime'        => $opt->getData("mtime", null, "intval"),
        ];


        // 判断是否已经提交（可能重复提交） ->where('verify', 0)
        $authDb   = new UserAuth();
        $authInfo = $authDb->where('uid', $myUid)->first();
        if($authInfo){
            $opt->throwIf(($authInfo['verify'] == 1), '你已经申请认证！');
            //$opt->throwIf(($authInfo['verify'] == 0) && ($authInfo['end_time'] > LARAVEL_TIME), '你已经申请认证,请等待审核！');
        }


        // 判断验证码
        //$smsDb = new SiteSms();
        //$where = ['mobile' => $mobile, 'code' => $code, "status" => "0"];
        //$sinfo = $smsDb->where($where)->orderBy("id", "DESC")->first();
        //$this->throwIf(empty($sinfo), '验证码错误！！');
        //$this->throwIf(LARAVEL_TIME - $sinfo->ctime > 600, '验证码超时！！');

        // 验证信息
        $rules  = ["auth_name" => 'required', "license_img" => 'required', "realname" => 'required', "position" => 'required', "areas" => 'required', "files" => 'required', "job_time" => 'required',];
        $rules  = ["auth_name" => 'required', "license_img" => 'required',];
        $msg    = ["auth_name" => '认证名称', "license_img" => '营业执照', "realname" => '真实姓名', "position" => '头衔', "areas" => '擅长领域', "description" => '描述', "files" => '证明文件', "job_time" => '从业年限',];
        $result = $userDb->validator($data, $rules, $msg);
        if($result === false){
            return $this->_returnFail($userDb->getError());
        }

        // 审核内容
        //$this->baiduTextCensor($data);

        // 保存
        $res = $authDb->onAuth($myUid, $data);
        if($res === false){
            return $this->_returnFail($authDb->getError());
        }

        // 获取认证信息
        $authInfo = $authDb->isCache(true)->oneFind(['uid' => $myUid]);
        if(empty($authInfo)){
            return $this->_returnFail('你的认证资料不存在！');
        }

        // $agent_uid = $uinfo['agent_uid'];
        // 判断支付金额
        $_money  = 300;
        $orderNo = $authInfo['order_no'];
        $body    = '组织认证';
        if($_money != $money){
            return $this->_returnFail('支付金额错误！');
        }
        if(empty($orderNo)){
            return $this->_returnFail('请传递订单号！');
        }

        $res = $this->savePayLog($myUid, $orderNo, $money, $body, 0, $authInfo['id']);
        if($res === false){
            return $this->_returnFail('保存支付信息失败');
        }

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }
        // 执行下单操作
        $result = $payV3->makeMiniPay($body, $orderNo, $openid, $money, $notify_url);
        if(!empty($result['code'])){
            return $this->_returnFail($result['message']);
        }
        // 给小程序返回可以直接调起支付的的json（也可以小程序自己制作）
        if($to_mini){
            return $this->toMiniJson($result['prepay_id']);
        }

        return $result;
    }

    // 退款 + 获取支付
    public function refundAndPay($myUid)
    {
        // 交易时间超过一年的订单无法提交退款（按支付成功时间+365天计算）
        $notify_url = $this->notifyUrl('refund');  // 回调

        // 订单时间
        // 退款用户状态
        $opt      = $this->option();
        $order_id = $opt->getData('order_id', 0, 'intval');
        $user_ids = $opt->getData('user_ids', [], 'is_array');  // 退款用户ID
        $money    = $opt->getData('money', 0, 'floatval');
        $openid   = $opt->getData('openid', null, 'trim');
        if(empty($order_id)){
            return $this->_returnFail('请传递退款订单编号！');
        }
        if(empty($user_ids)){
            return $this->_returnFail('请传递退款报名用户！');
        }
        if(empty($money)){
            return $this->_returnFail('请传递支付金额！');
        }

        // 执行下单
        $orderDb = new Order();
        $result  = $orderDb->refundOrder($myUid, $order_id, $user_ids);
        if($result === false){
            return $this->_returnFail($orderDb->getError());
        }
        if(empty($result['verify']) || ($result['verify'] != 1)){
            return $this->_returnFail('暂未通过审核，不能退款！');
        }

        // 退单金额错误
        $_money  = $result['money'];
        $orderNo = $result['order_no'];
        if($_money != $money){
            return $this->_returnFail('支付金额错误！');
        }

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        $result = $payV3->refund($result['old_no'], $orderNo, $money, $notify_url);
        $result = json_decode($result, true);

        return $result;
    }

    // 提现


    #######################################################################################
    ## 仅支付

    // 支付分步骤：第二步：已经下单，继续支付
    public function eventPay()
    {
        $notify_url = $this->notifyUrl('event');  // 回调

        $opt     = $this->option();
        $money   = $opt->getData('money', 0, 'floatval');
        $openid  = $opt->getData('openid', null, 'trim');
        $orderNo = $opt->getData('order_no', null, 'trim');
        $to_mini = $opt->getData('to_mini', 0, 'intval');  // 是否转换为小程序请求调用的json 默认不转换
        $body    = '报名参加活动';

        // 订单信息
        $orderInfo = (new Order())->isCache(true)->oneFind(['order_no' => $orderNo]);
        if(empty($orderInfo)){
            return $this->_returnFail('订单不存在！');
        }

        // 保存支付信息
        $res = $this->savePayLog($orderInfo['uid'], $orderNo, $money, $body, $orderInfo['id']);
        if($res === false){
            return $this->_returnFail('保存支付信息失败');
        }

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }
        $result = $payV3->makeMiniPay($body, $orderNo, $openid, $money, $notify_url);
        if(!empty($result['code'])){
            return $this->_returnFail($result['message']);
        }
        // 给小程序返回可以直接调起支付的的json（也可以小程序自己制作）
        if($to_mini){
            return $this->toMiniJson($result['prepay_id']);
        }

        return $result;
    }


    //  小程序支付：认证
    public function authPay($myUid)
    {
        $notify_url = $this->notifyUrl('auth');  // 回调

        $opt     = $this->option();
        $money   = $opt->getData('money', 0, 'floatval');
        $openid  = $opt->getData('openid', null, 'trim');
        $to_mini = $opt->getData('to_mini', 0, 'intval');  // 是否转换为小程序请求调用的json 默认不转换

        // 查询 配置信息
        if(empty($money)){
            return $this->_returnFail('请传递支付金额！');
        }

        // 获取认证信息  auth_price
        $authInfo = (new UserAuth())->isCache(true)->oneFind(['uid' => $myUid]);
        if(empty($authInfo)){
            return $this->_returnFail('你的认证资料不存在！');
        }
        // 查询用户信息 获取代理商信息
        $userInfo = (new User())->isCache(true)->oneFind(['id' => $myUid]);
        if(empty($userInfo)){
            return $this->_returnFail('该操作用户不存在！');
        }


        // $agent_uid = $userInfo['agent_uid'];
        // 判断支付金额
        $siteConf = $this->getSiteConfig();
        $_money   = $siteConf['auth_price'] ?? 0;  // 500元
        if(empty($_money)){
            return $this->_returnFail('请在管理后台设置认证支付金额！');
        }

        // 判断支付金额
        $orderNo = $authInfo['order_no'];
        $body    = '组织认证';
        if($_money != $money){
            return $this->_returnFail('支付金额错误！');
        }
        if(empty($orderNo)){
            return $this->_returnFail('请传递订单号！');
        }

        $res = $this->savePayLog($myUid, $orderNo, $money, $body, 0, $authInfo['id']);
        if($res === false){
            return $this->_returnFail('保存支付信息失败');
        }

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }
        // 执行下单操作
        $result = $payV3->makeMiniPay($body, $orderNo, $openid, $money, $notify_url);
        if(!empty($result['code'])){
            return $this->_returnFail($result['message']);
        }

        // 给小程序返回可以直接调起支付的的json（也可以小程序自己制作）
        if($to_mini){
            return $this->toMiniJson($result['prepay_id']);
        }

        return $result;
    }


    // 退款 + 获取支付
    public function refundPay()
    {
        // 交易时间超过一年的订单无法提交退款（按支付成功时间+365天计算）
        $notify_url = $this->notifyUrl('refund');  // 回调

        // 订单时间
        // 退款用户状态
        $opt     = $this->option();
        $money   = $opt->getData('money', 0, 'floatval');
        $orderNo = $opt->getData('order_no', null, 'trim');
        if(empty($orderNo)){
            return $this->_returnFail('请传递退款订单编号！');
        }
        if(empty($money)){
            return $this->_returnFail('请传递支付金额！');
        }

        // 订单信息
        $orderInfo = (new Order())->isCache(true)->oneFind(['order_no' => $orderNo]);
        if(empty($orderInfo)){
            return $this->_returnFail('订单不存在！');
        }
        if($orderInfo['verify'] != 1){
            return $this->_returnFail('暂未通过审核，不能退款！');
        }

        // 退单金额错误
        $_money = $orderInfo['money'];
        if($_money != $money){
            return $this->_returnFail('支付金额错误！');
        }

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }
        // 制作 header
        $result = $payV3->refund($orderInfo['old_no'], $orderNo, $money, $notify_url);
        $result = json_decode($result, true);

        return $result;
    }



    #######################################################################################
    ## 支付测试

    //  H5支付
    public function h5Pay()
    {
        $description = 'Image形象店-深圳腾大-QQ公仔';
        $notify_url  = $this->notifyUrl('h5');  // 回调

        $opt      = $this->option();
        $money    = $opt->getData('money', 0, 'floatval');
        $trade_no = $opt->getData('trade_no', null, 'trim');
        if(empty($money)){
            return $this->_returnFail('请传递支付金额！');
        }
        if(empty($trade_no)){
            return $this->_returnFail('请传递订单号！');
        }

        // 配置信息
        $config = Config::get('wx');

        //请求参数(报文主体)
        $apiUrl = 'https://api.mch.weixin.qq.com/v3/pay/transactions/h5';   //H5支付
        $body   = [
            'appid'        => $config['wx_mini_appid'],
            'mchid'        => $config['wx_mchid'],
            'description'  => $description,
            'out_trade_no' => $trade_no,
            'notify_url'   => $notify_url,
            'amount'       => [
                'total'    => $money * 100,
                'currency' => 'CNY',
            ],
            'scene_info'   => [
                'payer_client_ip' => Request::instance()->ip(),
                'h5_info'         => [
                    'type' => 'Wap',
                ],
            ],
        ];

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        // 制作 header
        // {"prepay_id" : "wx201410272009395522657a690389285100"}
        $headers = $payV3->sign('POST', $apiUrl, json_encode($body));
        $result  = $payV3->curlPost($apiUrl, json_encode($body), $headers);


        return $result;
    }


    //  APP支付
    public function appPay()
    {
        $description = 'Image形象店-深圳腾大-QQ公仔';
        $notify_url  = $this->notifyUrl('app');  // 回调

        $opt      = $this->option();
        $money    = $opt->getData('money', 0, 'floatval');
        $trade_no = $opt->getData('trade_no', null, 'trim');
        if(empty($money)){
            return $this->_returnFail('请传递支付金额！');
        }
        if(empty($trade_no)){
            return $this->_returnFail('请传递订单号！');
        }

        // 配置信息
        $config = Config::get('wx');

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        // 执行操作
        $apiUrl  = 'https://api.mch.weixin.qq.com/v3/pay/transactions/app';  // APP支付
        $body    = [
            'appid'        => $config['wx_mini_appid'],
            'mchid'        => $config['wx_mchid'],
            'description'  => $description,
            'out_trade_no' => $trade_no,
            'notify_url'   => $notify_url,
            'amount'       => [
                'total'    => $money * 100,
                'currency' => 'CNY',
            ],
        ];
        $headers = $payV3->sign('POST', $apiUrl, json_encode($body));

        return $payV3->curlPost($apiUrl, json_encode($body), $headers);
    }


    // H5测试支付
    public function testPay()
    {
        $url  = 'https://api.mch.weixin.qq.com/v3/pay/transactions/h5';
        $body = [
            'appid'        => '******',
            'mchid'        => '******',
            'description'  => '******',
            'out_trade_no' => date('YmdHis').rand(1000, 9999),
            'notify_url'   => "******",
            'amount'       => [
                'total'    => 100,
                'currency' => 'CNY',
            ],
            'scene_info'   => [
                'payer_client_ip' => Request::instance()->ip(),
                'h5_info'         => [
                    'type' => 'Wap',
                ],
            ],
        ];

        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        // 支付
        $headers = $payV3->sign('POST', $url, json_encode($body));
        $res     = $payV3->curlPost($url, $body, $headers);

        return $res;
    }

    #######################################################################################
    ## 回调

    // 认证返回 操作
    public function authNotify()
    {
        // 用户认证：end_time  auth_time
        // 用户认证：form_time  end_time is_pay  pay_time


        // 支付成功 后 的操作
        //$xmlInfo = $GLOBALS['HTTP_RAW_POST_DATA'];
        //$xmlInfo   = file_get_contents("php://input");
        $arrayInfo = $this->checkNotify();
        if($arrayInfo === false){
            return $this->_returnFail($this->error);
        }

        // 整理验证数据
        $ctime       = LARAVEL_TIME;
        $trade_no    = $arrayInfo['out_trade_no'];
        $trade_type  = $arrayInfo['trade_type'];  // JSAPI
        $trade_state = $arrayInfo['trade_state'];  // SUCCESS
        if($trade_state != 'SUCCESS'){
            return $this->_returnFail('支付状态：'.$trade_state);
        }

        // 获取配置信息
        $siteConf   = $this->getSiteConfig();
        $agent_rate = $siteConf['agent_rate'] ?? 0;
        $end_time   = mktime(0, 0, 0, date("m"), date("d") + 1, date("Y") + 1);

        //$card = ExchangeCard::query()->where('card_num', $card_num)->lockForUpdate()->first();
        //$card = ExchangeCard::query()->where('card_num', $card_num)->lockForUpdate()->first();
        // 实例化 执行操作
        $auhtDb = new UserAuth();
        $userDb = new User();
        $monDb  = new UserMoney();
        $proDb  = new UserProfit();
        $payDb  = new UserPay();
        $pro2Db = new UserProfit2();

        // 保存信息
        DB::beginTransaction();
        try{

            // 获取支付信息 判断是否已经完成支付
            $payInfo = $payDb->where('trade_no', $trade_no)->lockForUpdate()->first();
            $this->throwIf(empty($payInfo), '你的支付信息不存在！');
            $this->throwIf(($payInfo['status'] == 1) && ($payInfo['pay_time']), '你的支付已经完成！');   // 避免重复支付


            // 获取认证信息
            $authInfo = $auhtDb->where('order_no', $trade_no)->lockForUpdate()->first();
            $this->throwIf(empty($authInfo), '你的认证资料不存在！');


            // 查询用户信息 获取代理商信息
            $userInfo = $userDb->where('id', $authInfo['uid'])->lockForUpdate()->first();
            $this->throwIf(empty($userInfo), '该操作用户不存在！');


            // 参数    组合用于更新的数据
            $user_id   = $userInfo['id'];
            $agent_uid = $userInfo['agent_uid'];  // 代理商
            $userData  = ['end_time' => $end_time, 'auth_time' => $ctime,];
            $authData  = ['end_time' => $end_time, 'form_time' => $ctime, 'is_pay' => 1, 'pay_time' => $ctime,];
            $payData   = ['status' => 1, 'pay_time' => $ctime,];

            // 用户收益
            $monData = $userMon = [];
            if(($authInfo['times'] == 1) && $agent_uid){
                $money    = $payInfo['money'] * $agent_rate / 100;
                $monData  = ['uid' => $agent_uid, 'form_uid' => $user_id, 'total' => $payInfo['money'], 'money' => $money, 'type' => 'auth', 'description' => '用户认证'];
                $proData  = ['uid' => $agent_uid, 'form_uid' => $user_id, 'total' => $payInfo['money'], 'profit' => $money, 'type' => 'auth', 'description' => '用户认证', 'ctime' => $ctime, 'mtime' => $ctime,];
                $pro2Data = ['uid' => $agent_uid, 'form_uid' => $user_id, 'total' => $payInfo['money'], 'auth_profit' => $money, 'description' => '用户认证', 'ctime' => $ctime, 'mtime' => $ctime,];
                $userMon  = ['money' => DB::raw("money+".$money),];

                $monDb->fill($monData);
                $proDb->fill($proData);
                $pro2Db->fill($pro2Data);
            }


            // 改变用户信息
            $result = $userDb->where('id', $user_id)->update($userData);

            // 改变用户认证
            $result = $auhtDb->where('id', $authInfo['id'])->update($authData);

            // 用户收益
            if($monData){
                // 用户资金记录
                $monDb->save();
                // 用户收益记录
                $proDb->save();
                // 用户收益记录2
                $pro2Db->save();
                // 更新用户余额
                $result = $userDb->where('id', $agent_uid)->update($userMon);
            }

            // 用户支付记录
            $result = $payDb->where('id', $payInfo['id'])->update($payData);

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->_returnFail($e->getMessage());
        }


        // 删除缓存
        $payDb->deleteCacheShow($payInfo);
        $auhtDb->deleteCacheShow($authInfo);
        $userDb->deleteCacheShow($userInfo, ['id' => $agent_uid]);
        if($agent_uid){
            $monDb->deleteCacheShow(['uid' => $agent_uid]);
            $proDb->deleteCacheShow(['uid' => $agent_uid]);
            $pro2Db->deleteCacheShow(['uid' => $agent_uid]);
        }


        return true;
    }


    // 活动报名 操作
    public function eventNotify()
    {
        // 支付状态
        //   paytime status
        //  用户金额
        //  付款记录

        // 支付成功 后 的操作
        //$xmlInfo = $GLOBALS['HTTP_RAW_POST_DATA'];
        //$xmlInfo   = file_get_contents("php://input");
        $arrayInfo = $this->checkNotify();
        if($arrayInfo === false){
            return $this->_returnFail($this->error);
        }

        // 整理验证数据
        $trade_no    = $arrayInfo['out_trade_no'];
        $trade_type  = $arrayInfo['trade_type'];  // JSAPI
        $trade_state = $arrayInfo['trade_state'];  // SUCCESS
        // 参数
        $ctime     = LARAVEL_TIME;
        $orderData = ['status' => 1, 'pay_time' => $ctime,];
        $payData   = ['status' => 1, 'pay_time' => $ctime,];
        if($trade_state != 'SUCCESS'){
            return $this->_returnFail('支付状态：'.$trade_state);
        }


        // 实例化 执行操作
        $orderDb = new Order();
        $orMonDb = new OrderMoney();
        $userDb  = new User();
        $payDb   = new UserPay();
        $monDb   = new UserMoney();
        $proDb   = new UserProfit();
        $pro2Db  = new UserProfit2();


        // 保存信息
        DB::beginTransaction();
        try{

            // 订单信息
            $orderInfo = $orderDb->where('order_no', $trade_no)->lockForUpdate()->first();
            $this->throwIf(empty($orderInfo), '你的订单不存在！');
            $this->throwIf(($orderInfo['status'] == 1) && ($orderInfo['pay_time']), '你的支付dingdan 已经完成！');   // 避免重复支付

            // 获取支付信息
            $payInfo = $payDb->where('order_no', $trade_no)->lockForUpdate()->first();
            $this->throwIf(empty($payInfo), '你的支付信息不存在！');
            $this->throwIf(($payInfo['status'] == 1) && ($payInfo['pay_time']), '你的支付已经完成！');   // 避免重复支付


            // 获取订单金额信息
            $moenyInfo = $orMonDb->where('order_id', $orderInfo['id'])->lockForUpdate()->first();
            $this->throwIf(empty($moenyInfo), '你的订单金额信息不存在！');


            // 用户收益
            $total      = $moenyInfo['pay_money'];
            $order_id   = $orderInfo['id'];
            $uidMoney   = $agentMoney = $shareMoney = $publishMoney = [];
            $uidBalance = $agentBalance = $shareBalance = $publishBalance = [];
            $pro2Data   = [];
            if($moenyInfo['uid'] && $moenyInfo['uid_money']){
                $mon_uid    = $moenyInfo['uid'];
                $uid_money  = $moenyInfo['uid_money'];
                $uidBalance = ['money_freeze' => DB::raw("money_freeze+".$uid_money),];
                $uidMoney   = ['uid' => $mon_uid, 'money' => $uid_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $uidProfit  = ['uid' => $mon_uid, 'profit' => $uid_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$mon_uid])){
                    $pro2Data[$mon_uid] = ['uid' => $mon_uid, 'order_profit' => $uid_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$mon_uid]['order_profit'] = $uid_money;
                }
            }
            if($moenyInfo['agent_uid'] && $moenyInfo['agent_money']){
                $agent_uid    = $moenyInfo['agent_uid'];
                $agent_money  = $moenyInfo['agent_money'];
                $agentBalance = ['money_freeze' => DB::raw("money_freeze+".$agent_money),];
                $agentMoney   = ['uid' => $agent_uid, 'money' => $agent_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $agentProfit  = ['uid' => $agent_uid, 'profit' => $agent_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$agent_uid])){
                    $pro2Data[$agent_uid] = ['uid' => $agent_uid, 'agent_profit' => $agent_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$agent_uid]['agent_profit'] = $agent_money;
                }
            }
            if($moenyInfo['share_uid'] && $moenyInfo['share_money']){
                $share_uid    = $moenyInfo['share_uid'];
                $share_money  = $moenyInfo['share_money'];
                $shareBalance = ['money_freeze' => DB::raw("money_freeze+".$share_money),];
                $shareMoney   = ['uid' => $share_uid, 'money' => $share_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $shareProfit  = ['uid' => $share_uid, 'profit' => $share_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$share_uid])){
                    $pro2Data[$share_uid] = ['uid' => $share_uid, 'share_profit' => $share_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$share_uid]['share_profit'] = $share_money;
                }
            }
            if($moenyInfo['publish_uid'] && $moenyInfo['publish_money']){
                $publish_uid    = $moenyInfo['publish_uid'];
                $publish_money  = $moenyInfo['publish_money'];
                $publishBalance = ['money_freeze' => DB::raw("money_freeze+".$publish_money),];
                $publishMoney   = ['uid' => $publish_uid, 'money' => $publish_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $publishProfit  = ['uid' => $publish_uid, 'profit' => $publish_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$publish_uid])){
                    $pro2Data[$publish_uid] = ['uid' => $publish_uid, 'publish_profit' => $publish_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$publish_uid]['publish_profit'] = $publish_money;
                }
            }


            // 改变订单信息
            $result = $orderDb->where('id', $order_id)->update($orderData);
            // 用户支付记录
            $result = $payDb->where('id', $payInfo['id'])->update($payData);

            // 用户收益
            if($uidMoney){
                // 用户资金记录
                $monDb->insert($uidMoney);
                // 用户收益明细
                $proDb->insert($uidProfit);
                // 更新用户余额
                $result = $userDb->where('id', $mon_uid)->update($uidBalance);
            }
            if($agentMoney){
                // 用户资金记录
                $monDb->insert($agentMoney);
                // 用户收益明细
                $proDb->insert($agentProfit);
                // 更新用户余额
                $result = $userDb->where('id', $agent_uid)->update($agentBalance);
            }
            if($shareMoney){
                // 用户资金记录
                $monDb->insert($shareMoney);
                // 用户收益明细
                $proDb->insert($shareProfit);
                // 更新用户余额
                $result = $userDb->where('id', $share_uid)->update($shareBalance);
            }
            if($publishMoney){
                // 用户资金记录
                $monDb->insert($publishMoney);
                // 用户收益明细
                $proDb->insert($publishProfit);
                // 更新用户余额
                $result = $userDb->where('id', $publish_uid)->update($publishBalance);
            }
            // 用户收益明细2
            if($pro2Data){
                foreach($pro2Data as $_row){
                    $pro2Db->insert($_row);
                }
            }

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->_returnFail($e->getMessage());
        }


        // 删除缓存
        $payDb->deleteCacheShow($payInfo);
        $orderDb->deleteCacheShow($orderInfo);
        $pro2Db->deleteCacheList($pro2Data);
        if(!empty($agent_uid)){
            $userDb->deleteCacheShow(['id' => $agent_uid]);
            $monDb->deleteCacheShow(['uid' => $agent_uid]);
            $proDb->deleteCacheShow(['uid' => $agent_uid]);
        }
        if(!empty($mon_uid)){
            $userDb->deleteCacheShow(['id' => $mon_uid]);
            $monDb->deleteCacheShow(['uid' => $mon_uid]);
            $proDb->deleteCacheShow(['uid' => $mon_uid]);
        }
        if(!empty($share_uid)){
            $userDb->deleteCacheShow(['id' => $share_uid]);
            $monDb->deleteCacheShow(['uid' => $share_uid]);
            $proDb->deleteCacheShow(['uid' => $share_uid]);
        }
        if(!empty($publish_uid)){
            $userDb->deleteCacheShow(['id' => $publish_uid]);
            $monDb->deleteCacheShow(['uid' => $publish_uid]);
            $proDb->deleteCacheShow(['uid' => $publish_uid]);
        }

        return true;
    }


    // 活动报名 退款 操作
    public function refundNotify()
    {
        // 支付状态
        //   paytime status
        //  用户金额
        //  付款记录
        // 支付成功 后 的操作


        //$xmlInfo = $GLOBALS['HTTP_RAW_POST_DATA'];
        //$xmlInfo   = file_get_contents("php://input");
        $arrayInfo = $this->checkNotify();
        if($arrayInfo === false){
            return $this->_returnFail($this->error);
        }

        // 整理验证数据
        $trade_no    = $arrayInfo['out_trade_no'];
        $trade_type  = $arrayInfo['trade_type'];  // JSAPI
        $trade_state = $arrayInfo['trade_state'];  // SUCCESS
        if($trade_state != 'SUCCESS'){
            return $this->_returnFail('支付状态：'.$trade_state);
        }


        // 实例化 执行操作
        $orderDb  = new Order();
        $orUserDb = new OrderUser();
        $orMonDb  = new OrderMoney();
        $userDb   = new User();
        $payDb    = new UserPay();
        $monDb    = new UserMoney();
        $proDb    = new UserProfit();
        $pro2Db   = new UserProfit2();

        // 参数
        $ctime     = LARAVEL_TIME;
        $orderData = ['status' => 1, 'pay_time' => $ctime,];
        $payData   = ['status' => 1, 'pay_time' => $ctime,];

        // 保存信息
        DB::beginTransaction();
        try{

            // 订单信息
            $orderInfo = $orderDb->where('order_no', $trade_no)->lockForUpdate()->first();
            $this->throwIf(empty($orderInfo), '你的订单不存在！');
            $this->throwIf(($orderInfo['status'] == 1) && ($orderInfo['pay_time']), '你的支付订单已经完成！');   // 避免重复支付


            // 获取支付信息
            $payInfo = $payDb->where('order_no', $trade_no)->lockForUpdate()->first();
            $this->throwIf(empty($payInfo), '你的支付信息不存在！');
            $this->throwIf(($payInfo['status'] == 1) && ($payInfo['pay_time']), '你的支付已经完成！');   // 避免重复支付


            // 获取订单金额信息
            $moenyInfo = $orMonDb->where('order_id', $orderInfo['id'])->lockForUpdate()->first();
            $this->throwIf(empty($moenyInfo), '你的订单金额信息不存在！');

            // 获取订单用户的订单用户ID
            $_orderUserIds = $orUserDb->where('order_id', $orderInfo['id'])->pluck();
            $this->throwIf(empty($_orderUserIds), '你的订单用户信息不存在！');

            // 用户收益
            $total      = $moenyInfo['pay_money'];
            $order_id   = $orderInfo['id'];
            $uidMoney   = $agentMoney = $shareMoney = $publishMoney = [];
            $uidBalance = $agentBalance = $shareBalance = $publishBalance = [];
            $pro2Data   = [];
            if($moenyInfo['uid'] && $moenyInfo['uid_money']){
                $mon_uid    = $moenyInfo['uid'];
                $uid_money  = $moenyInfo['uid_money'];
                $uidBalance = ['money_freeze' => DB::raw("money_freeze+".$uid_money),];
                $uidMoney   = ['uid' => $mon_uid, 'money' => $uid_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $uidProfit  = ['uid' => $mon_uid, 'profit' => $uid_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$mon_uid])){
                    $pro2Data[$mon_uid] = ['uid' => $mon_uid, 'order_profit' => $uid_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$mon_uid]['order_profit'] = $uid_money;
                }
            }
            if($moenyInfo['agent_uid'] && $moenyInfo['agent_money']){
                $agent_uid    = $moenyInfo['agent_uid'];
                $agent_money  = $moenyInfo['agent_money'];
                $agentBalance = ['money_freeze' => DB::raw("money_freeze+".$agent_money),];
                $agentMoney   = ['uid' => $agent_uid, 'money' => $agent_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $agentProfit  = ['uid' => $agent_uid, 'profit' => $agent_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$agent_uid])){
                    $pro2Data[$agent_uid] = ['uid' => $agent_uid, 'agent_profit' => $agent_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$agent_uid]['agent_profit'] = $agent_money;
                }
            }
            if($moenyInfo['share_uid'] && $moenyInfo['share_money']){
                $share_uid    = $moenyInfo['share_uid'];
                $share_money  = $moenyInfo['share_money'];
                $shareBalance = ['money_freeze' => DB::raw("money_freeze+".$share_money),];
                $shareMoney   = ['uid' => $share_uid, 'money' => $share_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $shareProfit  = ['uid' => $share_uid, 'profit' => $share_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$share_uid])){
                    $pro2Data[$share_uid] = ['uid' => $share_uid, 'share_profit' => $share_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$share_uid]['share_profit'] = $share_money;
                }
            }
            if($moenyInfo['publish_uid'] && $moenyInfo['publish_money']){
                $publish_uid    = $moenyInfo['publish_uid'];
                $publish_money  = $moenyInfo['publish_money'];
                $publishBalance = ['money_freeze' => DB::raw("money_freeze+".$publish_money),];
                $publishMoney   = ['uid' => $publish_uid, 'money' => $publish_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime,];
                $publishProfit  = ['uid' => $publish_uid, 'profit' => $publish_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'type' => 'order', 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                if(empty($pro2Data[$publish_uid])){
                    $pro2Data[$publish_uid] = ['uid' => $publish_uid, 'publish_profit' => $publish_money, 'form_uid' => $orderInfo['uid'], 'total' => $total, 'description' => '用户报名', 'ctime' => $ctime, 'mtime' => $ctime, 'order_id' => $order_id,];
                } else{
                    $pro2Data[$publish_uid]['publish_profit'] = $publish_money;
                }
            }


            // 改变订单信息
            $result = $orderDb->where('id', $order_id)->update($orderData);

            // 用户支付记录
            $result = $payDb->where('trade_no', $trade_no)->update($payData);


            // 原订单状态  is_refund:4 退款完成
            $result = $orderDb->where('id', $orderInfo['old_id'])->update(['is_refund' => 4]);
            // 原订单用户状态
            $result = $orUserDb->where('id', $_orderUserIds)->update(['status_refund' => 1]);

            // 用户收益
            if($uidMoney){
                // 用户资金记录
                $monDb->insert($uidMoney);
                // 用户收益明细
                $proDb->insert($uidProfit);
                // 更新用户余额
                $result = $userDb->where('id', $mon_uid)->update($uidBalance);
            }
            if($agentMoney){
                // 用户资金记录
                $monDb->insert($agentMoney);
                // 用户收益明细
                $proDb->insert($agentProfit);
                // 更新用户余额
                $result = $userDb->where('id', $agent_uid)->update($agentBalance);
            }
            if($shareMoney){
                // 用户资金记录
                $monDb->insert($shareMoney);
                // 用户收益明细
                $proDb->insert($shareProfit);
                // 更新用户余额
                $result = $userDb->where('id', $share_uid)->update($shareBalance);
            }
            if($publishMoney){
                // 用户资金记录
                $monDb->insert($publishMoney);
                // 用户收益明细
                $proDb->insert($publishProfit);
                // 更新用户余额
                $result = $userDb->where('id', $publish_uid)->update($publishBalance);
            }
            // 用户收益明细2
            if($pro2Data){
                foreach($pro2Data as $_row){
                    $pro2Db->insert($_row);
                }
            }

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->_returnFail($e->getMessage());
        }


        // 删除缓存
        $payDb->deleteCacheShow($payInfo);
        $orderDb->deleteCacheShow($orderInfo);
        $pro2Db->deleteCacheList($pro2Data);
        if(!empty($agent_uid)){
            $userDb->deleteCacheShow(['id' => $agent_uid]);
            $monDb->deleteCacheShow(['uid' => $agent_uid]);
            $proDb->deleteCacheShow(['uid' => $agent_uid]);
        }
        if(!empty($mon_uid)){
            $userDb->deleteCacheShow(['id' => $mon_uid]);
            $monDb->deleteCacheShow(['uid' => $mon_uid]);
            $proDb->deleteCacheShow(['uid' => $mon_uid]);
        }
        if(!empty($share_uid)){
            $userDb->deleteCacheShow(['id' => $share_uid]);
            $monDb->deleteCacheShow(['uid' => $share_uid]);
            $proDb->deleteCacheShow(['uid' => $share_uid]);
        }
        if(!empty($publish_uid)){
            $userDb->deleteCacheShow(['id' => $publish_uid]);
            $monDb->deleteCacheShow(['uid' => $publish_uid]);
            $proDb->deleteCacheShow(['uid' => $publish_uid]);
        }


        return true;
    }


    // 提现
    public function withdrawNotify()
    {
        // 支付成功 后 的操作
        $arrayInfo = $this->checkNotify();
        if($arrayInfo === false){
            return $this->_returnFail($this->error);
        }

        // 整理验证数据
        $trade_no    = $arrayInfo['out_trade_no'];
        $trade_type  = $arrayInfo['trade_type'];  // JSAPI
        $trade_state = $arrayInfo['trade_state'];  // SUCCESS
        if($trade_state != 'SUCCESS'){
            return $this->_returnFail('支付状态：'.$trade_state);
        }


        // 提现信息
        $withdDb = new UserWithdraw();
        $userDb  = new User();
        $moneyDb = new UserMoney();


        // 保存信息
        DB::beginTransaction();
        try{

            // 提现信息
            $withdInfo = $withdDb->where('trade_no', $trade_no)->lockForUpdate()->first();
            $this->throwIf(empty($withdInfo), '你提现信息不存在！');
            $this->throwIf($withdInfo['verify'] != 1, '你提现信息未通过审核！');
            $this->throwIf($withdInfo['status'] == 1, '你提现信息已经操作成功！');


            // 参数
            $_uid   = $withdInfo['uid'];
            $_money = $withdInfo['money'] * (-1);  // 各种操作中显示未负数
            // 用户资金记录
            $withdData  = ['status' => 1, 'verify' => 3,];  // 提现状态
            $uidBalance = ['money' => DB::raw("money+".$_money),];  // 现金记录
            $uidMoney   = ['uid' => $_uid, 'money' => $_money, 'form_uid' => 0, 'total' => $_money, 'type' => 'withdraw', 'description' => '用户提现', 'ctime' => LARAVEL_TIME, 'mtime' => LARAVEL_TIME,];


            // 用户资金记录
            $moneyDb->insert($uidMoney);

            // 更新用户余额
            $result = $userDb->where('id', $_uid)->update($uidBalance);

            // 提现状态
            $result = $withdDb->where('id', $withdInfo['id'])->update($withdData);


            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->_returnFail($e->getMessage());
        }

        // 删除缓存
        $withdDb->deleteCacheShow($withdInfo);
        $moneyDb->deleteCacheShow($uidMoney);
        $userDb->deleteCacheShow(['id' => $_uid]);

        return true;
    }


    // 支付返回之前的验证操作
    protected function checkNotify()
    {
        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        // 参数
        //$request = request();
        $request = $this->option()->request();
        $wx_all  = $request->all();
        $server  = $request->server();
        $xmlInfo = file_get_contents("php://input");
        $action  = $request->input('action');
        $payV3->logwx($action.":wx_xml", $xmlInfo);       // log打印保存
        $payV3->logwx($action.":wx_server", $server);     // log打印保存
        $payV3->logwx($action.":wx_all", $wx_all);     // log打印保存
        //$headers = $request->header();
        //$payV3->logwx($action.":wx_header", $headers);  // log打印保存*/

        /*####################################################################################################
        // 模拟参数
        $xmlInfoJson = '{"id":"d51eb70a-36b2-533a-a53f-bf7f9f66a874","create_time":"2024-08-28T17:00:38+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"AQrvvqiwTYwseIz9vFbBlrhIfowtjPCeiFvFODEvZr5koT7Ubgq/7uTiggmdrKcsuP56vZC6+dJN6T4wkplFNBq08qf0BLvEiQVtpyksZzbPrghQlL92bgMzRD2dVXN53utFycrOgmxtgnckYB5j40AkgSMcaDcpFvudqTQfTCKYo+ob//LOy1fRLUCAqFDwWMZCqMpLCbF4tdumUtiGNmGXQi87f5USqo1FUMfjIc2MjAq919oXCtJ71W6X1dy3vr+mfd7yR4qJWni6F6qI33CTHUcQqwlm2coRbpxcV6vxbsJfJdU9yU0WX3PDmII8MXml9JqBgvOCOJz7d7tSofT1C9vxhxu8LDCgXK9UysOXzg1kdlxya1giPV9ytjvh0MgKUsqiefoiRKquixsPfU4GCvmVFeu8tSf6SQMVS3VBatR3ESOYuox6L672IYscNdr2/9gCiR1LUIFGIHp6jR5NR+B1/SBMb665EKBVTaPk+Ey3R/MJl8HymrN/8VixWkj4qzejI//qfwliQ99wP8gPUT+loMZ3f2h9h+mZvAY1iKX0uvJzHMl+HJ+MgXrTXQk8j/7i","associated_data":"transaction","nonce":"sZtIHfWK309O"}}';
        $serverJson  = '{"USER":"www","HOME":"\/home\/www","HTTP_WECHATPAY_TIMESTAMP":"1724835701","HTTP_PRAGMA":"no-cache","HTTP_WECHATPAY_SIGNATURE_TYPE":"WECHATPAY2-SHA256-RSA2048","HTTP_WECHATPAY_SIGNATURE":"ekts2RivdHixc\/lhvnVpgpCnhTV\/Vghs024GDPrQNalG5JY5OVTPQWlFYgjQpibvaNFqeTg7mmznBp5pmzfz1\/+iFxenL6GVzq2iSl\/e+mV3v1bQ7kouCF0SsUq+67nTBGnh1duJR1Ny28cKtzuiVa378tkI9cEUliJQSfC09FHo3+f8dDbSRz\/HCkwfuQbxwbheJCvqE+2i2X5GrpYhHVuXqyH9dTrLleQKfXcjRnuMeNgG6lbdeNm2JvxjxBv5S6lLGUb5U8EmWVr3vJ8ZuBveb1jFaZz1QJc5F\/8NpJ+tT9nuumTpX3ter4E4gMdwODD9mSfv8t+KXyoxzxGeMQ==","HTTP_WECHATPAY_SERIAL":"3896D5569B26A2894CEE4D190E602E14B4985692","HTTP_CONTENT_TYPE":"application\/json","HTTP_WECHATPAY_NONCE":"3Z77RhkfgsDUYAdO7gIceRWPnVhjeH4V","HTTP_HOST":"artt.hiyiku.com","HTTP_ACCEPT":"*\/*","HTTP_USER_AGENT":"Mozilla\/4.0","HTTP_CONNECTION":"Keep-Alive","HTTP_CONTENT_LENGTH":"911","PATH_INFO":"","REDIRECT_STATUS":"200","SERVER_NAME":"artt.hiyiku.com","SERVER_PORT":"443","SERVER_ADDR":"172.22.21.48","REMOTE_PORT":"5000","REMOTE_ADDR":"183.3.234.45","SERVER_SOFTWARE":"nginx\/1.22.1","GATEWAY_INTERFACE":"CGI\/1.1","HTTPS":"on","REQUEST_SCHEME":"https","SERVER_PROTOCOL":"HTTP\/1.1","DOCUMENT_ROOT":"\/www\/wwwroot\/art\/laravel\/public","DOCUMENT_URI":"\/index.php","REQUEST_URI":"\/mobile\/pay\/auth-notify","SCRIPT_NAME":"\/index.php","CONTENT_LENGTH":"911","CONTENT_TYPE":"application\/json","REQUEST_METHOD":"POST","QUERY_STRING":"","SCRIPT_FILENAME":"\/www\/wwwroot\/art\/laravel\/public\/index.php","FCGI_ROLE":"RESPONDER","PHP_SELF":"\/index.php","REQUEST_TIME_FLOAT":1724835701.256645,"REQUEST_TIME":1724835701}';
        $xmlInfo     = json_decode($xmlInfoJson, true);
        $server      = json_decode($serverJson, true);
        // 模拟参数
        ####################################################################################################*/

        // 验证签名
        if(empty($xmlInfo) || empty($server['HTTP_WECHATPAY_SIGNATURE'])){
            $payV3->logwx($action.":HTTP_WECHATPAY_SIGNATURE:微信返回数据不完整");     // log打印保存

            return $this->_returnFail("微信返回数据不完整！");
        }
        // 1、检查返回的平台序列号 与  用户自己持有的平台序列号是否一致
        //    如果不一致 则更新证书
        $has_serial = Config::get('wx.serial_platform');
        $res_serial = trim($server['HTTP_WECHATPAY_SERIAL']);
        $timestamp  = trim($server['HTTP_WECHATPAY_TIMESTAMP']); // 微信签名的时间戳
        $nonce      = trim($server['HTTP_WECHATPAY_NONCE']);     // 应答随机串
        $signature  = trim($server['HTTP_WECHATPAY_SIGNATURE']); // 应答签名
        if($has_serial != $res_serial){
            $payV3->logwx($action.":wx_xml:返回错误：平台证书文件序列号不一致！");  //log打印保存

            return $this->_returnFail("平台证书文件序列号不一致，请删除平台证书文件修改配置的证书序列号！");
        }

        // 验证应答签名
        $body       = ['timestamp' => $timestamp, 'nonce' => $nonce, 'data' => $xmlInfo,];
        $verifySign = $payV3->verifySign($body, $signature);
        $payV3->logwx($action.":验证签名结束".var_export($verifySign, 1));  //log打印保存
        if(!$verifySign){
            $payV3->logwx($action.":签名验证:失败！");  //log打印保存

            return $this->_returnFail("签名验证失败！");
        }

        $payV3->logwx($action.":wx_xml解析开始");  //log打印保存
        //解析xml
        //$arrayInfo = is_array($xmlInfo) ? $xmlInfo : (array)simplexml_load_string($xmlInfo, 'SimpleXMLElement', LIBXML_NOCDATA);
        $arrayInfo = is_array($xmlInfo) ? $xmlInfo : json_decode($xmlInfo, true);
        $payV3->logwx($action.":wx_xml解析", $arrayInfo);  //log打印保存
        if(empty($arrayInfo['event_type']) || ($arrayInfo['event_type'] != 'TRANSACTION.SUCCESS')){
            $this->error = $arrayInfo['summary'];
            $payV3->logwx($action.":wx_xml:返回错误：支付失败！");  //log打印保存

            return false;
        }

        // 解密回调数据
        $resource   = $arrayInfo['resource'];
        $ciphertext = $resource['ciphertext'];
        $nonceStr   = $resource['nonce'];
        $associated = $resource['associated_data'];  // 附加数据
        // 解密
        $string = $payV3->decryptToString($associated, $nonceStr, $ciphertext);
        $return = json_decode($string, true);
        if(empty($return)){
            $this->error = '回调解密失败！';
            $payV3->logwx("wx_xml:返回错误：回调解密失败！");  //log打印保存

            return false;
        }

        $payV3->logwx($action.":wx_data：解密数据:".json_encode($return));//log打印保存

        return $return;
    }


    #######################################################################################
    // 保存支付记录
    protected function savePayLog($uid, $trade_no, $money, $description, $order_id = 0, $auth_id = 0)
    {
        // 保存支付记录
        $payDb = new UserPay();
        $info  = $payDb->where('trade_no', $trade_no)->first();
        if($info){
            return true;
        }

        $_type   = $auth_id ? 'auth' : 'order';
        $payData = ['uid' => $uid, 'auth_id' => $auth_id, 'order_id' => $order_id, 'type' => $_type, 'trade_no' => $trade_no, 'money' => $money, 'description' => $description,];
        $payDb->fill($payData);
        $payDb->save();

        return true;
    }


    // 制作返回路径
    protected function notifyUrl($str)
    {
        $domain = request()->getHost();
        $url    = 'https://'.$domain.'/mobile/pay/'.$str.'-notify';

        return $url;
    }

    // 给前段小程序返回可以调用的json
    //   下面可以由小程序自己执行生成操作
    protected function toMiniJson($prepayid)
    {
        // 实例化
        $payV3 = $this->payV3();
        if($payV3 === false){
            return false;
        }

        $time2    = time();
        $paramarr = $payV3->toJsPay($time2, $prepayid);

        return $paramarr;
    }

    // 获取站点配置信息
    protected function getSiteConfig()
    {
        $siteConf = (new SiteConfig())->isCache(true)->getConfig();
        $siteConf = array_column($siteConf, 'value', 'field');

        return $siteConf;
    }

    // 抛出异常 主要是有锁表的事务中
    protected function throwIf($condition, $msg)
    {
        if($condition){
            throw new \Exception($msg);
        }
    }

}


